/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package dao

import (
	"fmt"
	"prim-server/common"
	"prim-server/model"

	"github.com/astaxie/beego/orm"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

type UserDao struct {
	BaseDao
}

type IUserDao interface {
	SaveUserInfo(user *model.User) error
	DeleteUserInfo(userId string) error
	GetUserInfo(queryParameter *common.QueryUserDetail) (users []*model.User, totalCount int, err error)
	UpdateAllUserInfo(modifyParameter *common.ModifyUserDetail) error
}

func GetUserDao() IUserDao {
	dao := &UserDao{}
	dao.Init()
	return dao
}

func (ud *UserDao) SaveUserInfo(user *model.User) error {
	if user == nil {
		return nil
	}
	_, err := ud.O.Insert(user)
	if err != nil {
		return errors.Errorf("SaveUserInfo error: %v, userId: %s", err, user.Id)
	}
	return nil
}
func (ud *UserDao) DeleteUserInfo(userId string) error {
	if len(userId) == 0 {
		return nil
	}
	user := new(model.User)
	user.Id = userId
	_, err := ud.O.Delete(user, "id")
	if err != nil {
		return errors.Errorf("DeleteUserInfo error: %v, userId: %s", err, userId)
	}
	return nil
}

func (ud *UserDao) GetUserInfo(queryParameter *common.QueryUserDetail) (users []*model.User, totalCount int, err error) {
	if queryParameter == nil {
		return nil, 0, nil
	}
	recode := ud.O.QueryTable(&model.User{})
	finalCondition := orm.NewCondition()
	if len(queryParameter.UserId) > 0 {
		finalCondition = finalCondition.And("id__in", queryParameter.UserId)
	}
	if len(queryParameter.UserName) > 0 {
		finalCondition = finalCondition.And("name__in", queryParameter.UserName)
	}
	if len(queryParameter.PhoneNumber) > 0 {
		finalCondition = finalCondition.And("phone_number__in", queryParameter.PhoneNumber)
	}
	if len(queryParameter.Locked) > 0 {
		finalCondition = finalCondition.And("locked__in", queryParameter.Locked)
	}
	if len(queryParameter.PwdChanged) > 0 {
		finalCondition = finalCondition.And("pwdchanged__in", queryParameter.PwdChanged)
	}
	offset, pageSize := ud.GetOffsetAndPageSize(queryParameter.Page, queryParameter.PageSize)
	recode = recode.SetCond(finalCondition)
	totalCount64, err := recode.Count()
	if err != nil {
		return nil, 0, errors.Errorf("GetUserInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	totalCount = cast.ToInt(totalCount64)
	_, err = recode.Offset(offset).Limit(pageSize).RelatedSel().All(&users)
	if err != nil {
		if err == orm.ErrNoRows {
			//not found
			return nil, 0, nil
		}
		//found error
		return nil, 0, errors.Errorf("GetUserInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	return users, totalCount, nil
}
func (ud *UserDao) UpdateAllUserInfo(modifyParameter *common.ModifyUserDetail) error {
	if modifyParameter == nil {
		return nil
	}
	modify := orm.Params{}
	if modifyParameter.Password != nil {
		modify["password"] = *modifyParameter.Password
		modify["salt"] = *modifyParameter.Salt
		modify["pwdchanged"] = true
	}
	if modifyParameter.Authenticated != nil {
		modify["authenticated"] = *modifyParameter.Authenticated
	}
	if modifyParameter.ProfilePhotoUrl != nil {
		modify["profile_photo_url"] = *modifyParameter.ProfilePhotoUrl
	}
	if modifyParameter.Lock != nil {
		modify["locked"] = *modifyParameter.Lock
	}
	if modifyParameter.FailTimes != nil {
		modify["fail_times"] = *modifyParameter.FailTimes
	}
	if modifyParameter.LockTime != nil {
		modify["locked_time"] = ud.ConvertToUTC(*modifyParameter.LockTime)
	}
	if modifyParameter.PhoneNumber != nil {
		modify["phone_number"] = *modifyParameter.PhoneNumber
	}
	if len(modify) != 0 {
		_, err := ud.O.QueryTable(&model.User{}).Filter("id", modifyParameter.UserId).Update(modify)
		if err != nil {
			return errors.Errorf("UpdateAllUserInfo error: %v, userId: %s", err, modifyParameter.UserId)
		}
	}
	return nil
}
